#include <stdio.h>
#include <thread>
#include <math.h>

#define SHM_QUEUE_IMPLEMENTATION
#define SHM_NOTIFY_IMPLEMENTATION


#if _WIN32
#include "shm_queue_win.h"
#include "shm_notify_win.h"
#else
#include "shm_queue_linux.h"
#include "shm_notify_linux.h"
#endif

bool running = true;


int main() {
  int rslt;
  shm_notify_t wnotify, rnotify;
  shm_queue_t wqueue, rqueue;

  rslt = shm_notify_open(&wnotify, "TestNotify");
  printf("shm_notify_open ret:%d\n", rslt);

  rslt = shm_notify_open(&rnotify, "TestNotify");
  printf("shm_notify_open ret:%d\n", rslt);

  shm_queue_options_t options;
  options.elem_count = 128;
  options.elem_size = 1024;
  options.mode = SHM_QUEUE_MODE_WRITE;
  options.name = "test";
  rslt = shm_queue_open(&wqueue, &options);
  printf("sq_open ret:%d\n", rslt);

  options.mode = SHM_QUEUE_MODE_READ;
  rslt = shm_queue_open(&rqueue, &options);
  printf("sq_open ret:%d\n", rslt);

  std::thread wthread1([&wqueue, &wnotify]() {
    while (running) {
      static const char str[] = "4321fdsafdsafdsafdsaf432143124321111111111143214rewrewqrewqrewrewqrewqr4321fdsafdsafdsafdsaf432143124321111111111143214rewrewqrewqrewrewqrewqr4321fdsafdsafdsafdsaf432143124321111111111143214rewrewqrewqrewrewqrewqr";
      int rslt = shm_queue_write(&wqueue, (void*)str, rand() % sizeof(str));
      shm_notify_send(&wnotify);
      //printf("shm_queue_write ret:%d\n", rslt);
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
  });

  std::thread rthread([&rqueue, &rnotify]() {
    char buffer[1024];
    while (running) {
      int rslt = shm_queue_read(&rqueue, buffer, sizeof(buffer));
      if (rslt > 0) {
        printf("shm_queue_read size:%d msgid:%u\n", rslt, rqueue.rmsgid);
      } else {
        shm_notify_wait(&rnotify, 1000);
      }
    }
  });

  getchar();
  running = false;
  wthread1.join();
  rthread.join();
  printf("finish\n");
  shm_queue_close(&wqueue);
  shm_queue_close(&rqueue);

  shm_notify_close(&wnotify);
  shm_notify_close(&rnotify);

  return 0;
}
